package com.example.security.aspect;

import com.example.security.annotation.DataScope;
import com.example.security.annotation.RequirePermission;
import com.example.security.common.BaseQuery;
import com.example.security.entity.SysUser;
import com.example.security.exception.BusinessException;
import com.example.security.service.SecurityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class PermissionAspect {

    private final SecurityService securityService;

    /**
     * 权限校验切面
     */
    @Around("@annotation(requirePermission)")
    public Object checkPermission(ProceedingJoinPoint point, RequirePermission requirePermission) throws Throwable {
        SysUser user = securityService.getCurrentUser();
        String permission = requirePermission.value();
        
        if (!securityService.hasPermission(user.getId(), permission)) {
            throw new BusinessException("您没有操作权限");
        }
        
        return point.proceed();
    }

    /**
     * 数据权限切面
     */
    @Around("@annotation(dataScope)")  
    public Object handleDataScope(ProceedingJoinPoint point, DataScope dataScope) throws Throwable {
        try {
            SysUser user = securityService.getCurrentUser();
            
            // 超级管理员不受限制
            if (securityService.isAdmin(user)) {
                return point.proceed();
            }
            
            // 获取数据权限SQL
            String sqlFilter = getDataScopeSql(user, dataScope);
            
            // 注入数据权限
            if (sqlFilter != null && !sqlFilter.isEmpty()) {
                Object params = point.getArgs()[0];
                if (params instanceof BaseQuery) {
                    ((BaseQuery) params).setDataScopeSql(sqlFilter);
                }
            }
            
            return point.proceed();
        } catch (Exception e) {
            log.error("数据权限处理异常", e);
            return point.proceed();
        }
    }

    /**
     * 生成数据权限SQL
     */
    private String getDataScopeSql(SysUser user, DataScope dataScope) {
        if (user == null || user.getDataScope() == null) {
            return null;
        }

        StringBuilder sqlFilter = new StringBuilder();
        String orgAlias = dataScope.orgAlias();
        String userAlias = dataScope.userAlias();
        
        switch (user.getDataScope()) {
            case "1": // 全部数据
                break;
            case "2": // 本机构及以下
                sqlFilter.append(String.format(
                    " AND %s.org_id IN (SELECT id FROM sys_org WHERE id = %d OR find_in_set(%d, parent_ids))",
                    orgAlias, user.getOrgId(), user.getOrgId()
                ));
                break;
            case "3": // 本机构
                sqlFilter.append(String.format(" AND %s.org_id = %d", orgAlias, user.getOrgId()));
                break;
            case "4": // 仅本人
                sqlFilter.append(String.format(" AND %s.user_id = %d", userAlias, user.getId()));
                break;
            default:
                break;
        }
        return sqlFilter.length() > 0 ? sqlFilter.toString() : null;
    }
} 